using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using Bzure.Common.Transactions;

namespace Bzure.Common.Data
{
    public abstract partial class EntityMap<T>
    {
        public EntityMap<T> SetDirection(ParameterDirection direction)
        {
            if (_command.Parameters.Count == 0) return this;

            DbParameter parameter = _command.Parameters[_command.Parameters.Count - 1];
            parameter.Direction = direction;

            return this;
        }

        public object GetParamValue(string paramName)
        {
            return _command.Parameters[paramName].Value;
        }
        public virtual EntityMap<T> AddParameter(DataMemberMap DataMemberMap)
        {
            DbParameter parameter = this._command.CreateParameter();
            string ParameterName = string.Format("@{0}", DataMemberMap.ParameterName);
            parameter.ParameterName = ParameterName;
            parameter.Value = DataMemberMap.DataValue;
            this._command.Parameters.Add(parameter);
            return this;
        }


        public abstract EntityMap<T> Add<TV>(string name, TV value);


        public abstract EntityMap<T> AddInt(string name);


        public abstract EntityMap<T> AddInt(string name, int value);

        public abstract EntityMap<T> AddInt(string name, int? value);


        public abstract EntityMap<T> AddLong(string name);


        public abstract EntityMap<T> AddLong(string name, long value);

        public abstract EntityMap<T> AddLong(string name, long? value);
        public abstract EntityMap<T> AddDecimal(string name);

        public abstract EntityMap<T> AddDecimal(string name, decimal value);

        public abstract EntityMap<T> AddDecimal(string name, decimal? value);


        public abstract EntityMap<T> AddDateTime(string name);
        public abstract EntityMap<T> AddDateTime(string name, DateTime value);

        public abstract EntityMap<T> AddDateTime(string name, DateTime? value);

        public abstract EntityMap<T> AddDateTime2(string name, DateTime value);

        public abstract EntityMap<T> AddDateTime2(string name, DateTime? value);

        public abstract EntityMap<T> AddString(string name, int size, string value);

        public abstract EntityMap<T> AddString(string name);

        public abstract EntityMap<T> AddString(string name, int size);

        public abstract EntityMap<T> AddString(string name, string value);

        public abstract EntityMap<T> AddGuid(string name);

        public abstract EntityMap<T> AddGuid(string name, Guid value);
        public abstract EntityMap<T> AddGuidID(string name);

        public abstract EntityMap<T> AddBoolean(string name);
        public abstract EntityMap<T> AddBoolean(string name, bool value);
        public abstract EntityMap<T> AddText(string name, String data);


    }

    public class SqlEntityMap<T> : EntityMap<T>
    {
        public SqlEntityMap(ITransactionSupport ContractProvider)
            : base(ContractProvider)
        {


        }

        public SqlEntityMap(ITransactionSupport ContractProvider, string commandText)
            : base(ContractProvider, commandText)
        {

        }
        public DbParameter CreateParam(string name, SqlDbType dataType, object value)
        {

            var param = new SqlParameter(name, dataType);
            param.Value = SetParamValue(value);
            _command.Parameters.Add(param);
            return param;
        }

        public DbParameter CreateParam(string name, SqlDbType dataType)
        {
            var param = new SqlParameter(name, dataType);
            _command.Parameters.Add(param);
            return param;
        }


        public override EntityMap<T> Add<TV>(string name, TV value)
        {
            var param = new SqlParameter(name, value);
            _command.Parameters.Add(param);
            return this;
        }

        public override EntityMap<T> AddInt(string name)
        {
            CreateParam(name, SqlDbType.Int);
            return this;
        }


        public override EntityMap<T> AddInt(string name, int value)
        {
            CreateParam(name, SqlDbType.Int, value);
            return this;
        }

        public override EntityMap<T> AddInt(string name, int? value)
        {
            CreateParam(name, SqlDbType.Int, value);
            return this;
        }


        public override EntityMap<T> AddLong(string name)
        {
            CreateParam(name, SqlDbType.BigInt);
            return this;
        }


        public override EntityMap<T> AddLong(string name, long value)
        {
            CreateParam(name, SqlDbType.BigInt, value);
            return this;
        }

        public override EntityMap<T> AddLong(string name, long? value)
        {
            CreateParam(name, SqlDbType.BigInt, value);
            return this;
        }
        public override EntityMap<T> AddDecimal(string name)
        {
            CreateParam(name, SqlDbType.Decimal);
            return this;
        }

        public override EntityMap<T> AddDecimal(string name, decimal value)
        {
            CreateParam(name, SqlDbType.Decimal, value);
            return this;
        }

        public override EntityMap<T> AddDecimal(string name, decimal? value)
        {
            CreateParam(name, SqlDbType.Decimal, value);
            return this;
        }


        public override EntityMap<T> AddDateTime(string name)
        {
            CreateParam(name, SqlDbType.DateTime);
            return this;
        }
        public override EntityMap<T> AddDateTime(string name, DateTime value)
        {
            CreateParam(name, SqlDbType.DateTime, value);
            return this;
        }

        public override EntityMap<T> AddDateTime(string name, DateTime? value)
        {
            CreateParam(name, SqlDbType.DateTime, value);
            return this;
        }

        public override EntityMap<T> AddDateTime2(string name, DateTime value)
        {
            CreateParam(name, SqlDbType.DateTime2, value);
            return this;
        }

        public override EntityMap<T> AddDateTime2(string name, DateTime? value)
        {
            CreateParam(name, SqlDbType.DateTime2, value);
            return this;
        }

        public override EntityMap<T> AddString(string name, int size, string value)
        {
            var param = CreateParam(name, SqlDbType.NVarChar, value);
            param.Size = size;
            return this;
        }

        public override EntityMap<T> AddString(string name)
        {
            CreateParam(name, SqlDbType.NVarChar);
            return this;
        }

        public override EntityMap<T> AddString(string name, int size)
        {
            var param = CreateParam(name, SqlDbType.NVarChar);
            param.Size = size;
            return this;
        }

        public override EntityMap<T> AddString(string name, string value)
        {
            CreateParam(name, SqlDbType.NVarChar, value);
            return this;
        }

        public override EntityMap<T> AddGuid(string name)
        {
            CreateParam(name, SqlDbType.UniqueIdentifier);
            return this;
        }

        public override EntityMap<T> AddGuid(string name, Guid value)
        {
            var param = CreateParam(name, SqlDbType.UniqueIdentifier);
            param.Value = SetGuidParamValue(value);
            return this;
        }
        public override EntityMap<T> AddGuidID(string name)
        {
            var param = CreateParam(name, SqlDbType.UniqueIdentifier);
            param.Value = SetGuidParamValue(Guid.NewGuid());
            return this;
        }

        public override EntityMap<T> AddBoolean(string name)
        {
            CreateParam(name, SqlDbType.Bit);
            return this;
        }
        public override EntityMap<T> AddBoolean(string name, bool value)
        {
            CreateParam(name, SqlDbType.Bit, value);
            return this;
        }
        public override EntityMap<T> AddText(string name, String data)
        {
            CreateParam(name, SqlDbType.NText, data);
            return this;
        }

    }

}